%% reads file and creates graphinstance
-module(graphReader).

%% ====================================================================
%% API functions
%% ====================================================================
-export([builtGraph/1]).


%% ====================================================================
%% External exports
%% ====================================================================

builtGraph(Filename) ->
    Device = openFile(Filename),
    Graph = graph:new(),
    Graphtype = getType(Device), 
    readLines(Graph, Device, Graphtype).

%% ====================================================================
%% Internal functions
%% ====================================================================

openFile(Filename) ->
    case file:open(Filename, read) of
      {ok, IO_Device} -> IO_Device;
      {error, Reason} -> io:write(Reason)
    end.

getType(Device) ->
    case file:read_line(Device) of
      {ok, Line}        -> if
                              Line =:= "#ungerichtet\n" -> "ungerichtet";
                              true -> "gerichtet"
                           end;
      eof               -> file:close(Device);
      {error, Reason}   -> io:write(Reason)
    end.

readLines(Graph, Device, Graphtype) ->
    case file:read_line(Device) of
      {ok, Line}        -> New_Graph = readLine(Graph, Line, Graphtype),
                           readLines(New_Graph, Device, Graphtype);
      eof               -> file:close(Device),
                           Graph;
      {error, Reason}   -> io:write(Reason)
    end.

readLine(Graph, Data, Graphtype) ->
    Pattern = "([a-z]+){1},([a-z]+){1},{0,1}([0-9]+){0,1},{0,1}([0-9]+){0,1}",
    Options =  [{capture, all_but_first, list}],
    case re:run(Data, Pattern, Options) of
        {match, Line} -> handleLine(Graph, Line, Graphtype);
        nomatch       -> io:write("ERROR in File")
    end.

handleLine(Graph, Line, Graphtype) ->
    [V1, V2 | R] = Line,
    {Graph1, ID_v1} = graph:addVertex(Graph, list_to_atom(V1)),
    {Graph2, ID_v2} = graph:addVertex(Graph1, list_to_atom(V2)),
    if
        Graphtype =:= "gerichtet"   -> {Graph3, _ID_edge} = graph:addEdgeD(Graph2, ID_v1, ID_v2);
        Graphtype =:= "ungerichtet" -> {Graph3, _ID_edge} = graph:addEdgeU(Graph2, ID_v1, ID_v2)
    end,
    
    case length(R) of
        0 -> Graph4 = Graph3;
        1 -> [C] = R,
             {Weight, _} = string:to_integer(C),
             Graph4 = graph:setValE(Graph3, _ID_edge, weight, Weight);
        2 -> [C, K] = R,
             {Weight, _} = string:to_integer(C),
             Graph4 = graph:setValE(Graph3, _ID_edge, weight, Weight),
             {Costs, _} = string:to_integer(K),
             Graph4 = graph:setValE(Graph4, _ID_edge, cost, Costs)
    end,
    Graph4.
